﻿using HslCommunication;
using HslCommunication.ModBus;
using HslCommunication.Profinet.Melsec;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

namespace MES
{
    //方科讯报警
    //    ICT                               FCT
    //D20.0	A轨调窄限位异常 K1                      D20.0	A轨调窄限位异常 K1
    //D20.1	出板轨调窄限位异常 K2                    D20.1	中轨调窄限位异常 K2
    //D20.2	平移轨调窄限位异常 K4                    D20.2	平移轨调窄限位异常 K4
    //D20.3	平移前限位异常 K8                             D20.3	平移前限位异常 K8
    //D20.4	平移后限位异常 K16                            D20.4	平移后限位异常 K16
    //D20.5	前门1打开...K32                            D20.5	前门1打开...K32
    //D20.6	设备未复位...K64                            D20.6	前门2打开...K64
    //D20.7	前门2打开...K128                            D20.7	设备未复位...K128
    //D20.8	后门1打开...K256                            D20.8	A治具气缸异常 K256
    //D20.9	后门2打开...K512                            D20.9	A轨阻挡气缸异常 K512
    //D20.A A治具气缸异常 K1024                            D20.A   A轨进板超时 K1024
    //D20.B A轨阻挡气缸异常    K2048                   D20.B A轨出板超时  K2048
    //D20.C A轨进板超时  K4096                            D20.C 中轨出板超时  K4096
    //D20.D A轨出板超时  K8192                            D20.D 中轨进板超时  K8192
    //D20.E 出板轨出板超时 K16384                            D20.E 平移出板超时  K16384
    //D20.F 出板轨进板超时 K32768                            D20.F 平移进板超时  K32768
    //D21.0	平移出板超时 K1                             D21.0	平移电机报警 K1
    //D21.1	平移进板超时 K2                             D21.1	平移轨道电机报警 K2
    //D21.2	平移电机报警 K4                             D21.2	A测试轨道电机报警 K4
    //D21.3	平移轨道电机报警 K8                             D21.3	中轨道电机报警 K8
    //D21.4	A测试轨道电机报警 K16                            D21.4	A天板气缸异常 K16
    //D21.5	出板轨道电机报警 K32                            D21.5	A测试超时 K32
    //D21.6	A测试超时 K64                                     D21.6	平移出板超时 K64
    //D21.7	天板气缸异常 K128                               D21.7	B轨调窄限位异常 K128
    //D21.8	缓存位存板满料 K256                               D21.8	B治具气缸异常 K256
    //D21.9	缓存升降2电机报警 K512                               D21.9	B轨阻挡气缸异常 K512
    //D20.A K1024   D20.A B轨进板超时  K1024
    //D20.B K2048   D20.B B轨出板超时  K2048
    //D20.C K4096   D20.C B测试轨道电机报警   K4096
    //D20.D K8192   D20.D B天板气缸异常 K8192
    //D20.E K16384  D20.E B测试超时   K16384
    //D21.F K32768  D21.F K32768

    public class Tool
    {
        public static Form1 form1 = new Form1();
        public static void SaveLog(Device device, string LogMod, string Log)
        {
            if (!Directory.Exists(Directory.GetCurrentDirectory() + @"\data\" + device.Name + @"\" + DateTime.Now.ToString("yyyyMMdd")))
            {
                Directory.CreateDirectory((Directory.GetCurrentDirectory() + @"\data\" + device.Name + @"\" + DateTime.Now.ToString("yyyyMMdd")));
            }
            //if (!File.Exists(Directory.GetCurrentDirectory() + @"\data\" + device.Name + @"\" + DateTime.Now.ToString("yyyyMMdd") + @"\" + LogMod + ".txt"))
            //{
            //    File.Create((Directory.GetCurrentDirectory() + @"\data\" + device.Name + @"\" + DateTime.Now.ToString("yyyyMMdd") + @"\" + LogMod + ".txt"));
            //}
            try
            {
                string appendLog = DateTime.Now.ToString("yyyy/MM/dd/HH:mm:ss.ff") + ":   " + Log + "\r\n";

                File.AppendAllText(Directory.GetCurrentDirectory() + @"\data\" + device.Name + @"\" + DateTime.Now.ToString("yyyyMMdd") + @"\" + LogMod + ".txt", appendLog);
            }
            catch
            {

            }


        }

        #region 上板机专用
        public static int SBJmode = 2;//AGV配送为1，手动上框为2
        public static Dictionary<string, int> SBJPortState = new Dictionary<string, int>()
        {
            //0为正常，1为执行动作
            {"1",0 },
            {"2",0 },
            {"3",0 },
            {"4",0 },
            {"5",0 },
            {"6",0 },
            {"7",0 },
            {"8",0 },
        };
        public static bool SBJ_ScanUsing = false;
        public static int SBJ_inputWaiteTime = 0;//扫码后等待一段时间再进板
        public static int stateKeepTime = 5000;//空料状态保持一段时间才向AGV要料
        public static Dictionary<string, int> CarrierID_A = new Dictionary<string, int>();//A轨条码队列
        public static Dictionary<string, int> CarrierID_B = new Dictionary<string, int>();//B轨条码队列

        public static int AGV_Load_Pos = 0;//AGV装载的轨道
        public static int AGV_UnLoad_Pos = 0;//AGV卸载的轨道
        public static int AGV_Pos = 0;//AGV当前的位置



        #endregion

        #region ICT,FCT

        public static Stopwatch ICT_FixetureTime = new Stopwatch();
        public static double ICT_StarTime = 0;
        public static double ICT_StopTime = 0;
        public static EDC_REPORT ICT_EDC_REPORT = new EDC_REPORT();

        public static Stopwatch FCT_FixetureTime1 = new Stopwatch();
        public static double FCT_StarTime1 = 0;
        public static double FCT_PartInTime1 = 0;
        public static double FCT_StopTime1 = 0;

        public static Stopwatch FCT_FixetureTime2 = new Stopwatch();
        public static double FCT_StarTime2 = 0;
        public static double FCT_PartInTime2 = 0;
        public static double FCT_StopTime2 = 0;

        public static string FCT_ID1 = "";
        public static string FCT_ID2 = "";
        public static EDC_REPORT FCT_EDC_REPORT = new EDC_REPORT();

        public static bool ICT_ScanUsing = false;
        public static bool FCT_ScanUsing = false;

        public static EDC_REPORT CheckEDCReport_ICT(string info, string PCBID, int ProcessTime, int FixetureTime, out List<string> testData,out string sorting)
        {
            sorting = "";
            EDC_REPORT EDC_REPORT = new EDC_REPORT();
            try
            {
                info = info.Substring(0, info.IndexOf("sec") + 3);
                string[] infoList = info.Split(',');
                testData = infoList.ToList();
                EDC_REPORT.ProductType = "";
                EDC_REPORT.ProcessMode = "Normal";
                EDC_REPORT.PCBQuantity = infoList[11];

                EDC_REPORT.JobID = PCBID;
                List<string> IDList = GetIDList(PCBID, Convert.ToInt32(EDC_REPORT.PCBQuantity),out sorting);
                string result = infoList[12];
                int PassNum = 0;
                EDC_REPORT.Pass = 1;
                for (int i = 0; i < result.Length; i++)
                {
                    if (result[i] == 'P')
                    {
                        EDC_REPORT.CheckResult += (IDList[i] + "_OK,");
                        PassNum++;
                    }
                    else
                    {
                        EDC_REPORT.Pass = 2;
                        EDC_REPORT.CheckResult += (IDList[i] + "_NG,");
                    }
                }
                EDC_REPORT.CheckResult = EDC_REPORT.CheckResult.Substring(0, EDC_REPORT.CheckResult.Length - 1);
                EDC_REPORT.InitialPassQuantity = PassNum.ToString();
                for (int i = 0; i < IDList.Count; i++)
                {
                    EDC_REPORT.PCBBarcode += IDList[i] + "*";
                }
                EDC_REPORT.PCBBarcode = EDC_REPORT.PCBBarcode.Substring(0, EDC_REPORT.PCBBarcode.Length - 1);

                double beginTime = Convert.ToDouble(infoList[infoList.Length - 7]);
                double overTime = Convert.ToDouble(infoList[5]);
                EDC_REPORT.EffectiveTime = Convert.ToInt32(overTime - beginTime);
                EDC_REPORT.AuxiliaryTime = FixetureTime - EDC_REPORT.EffectiveTime;
                EDC_REPORT.WaitingTime = ProcessTime - FixetureTime;

                EDC_REPORT.result = true;
            }
            catch
            {
                EDC_REPORT.result = false;
                testData = null;
            }
            return EDC_REPORT;
        }
        public static EDC_REPORT CheckEDCReport_FCT(string info, string PCBID, int ProcessTime, int FixetureTime, int WaiteTime, out List<string> testData,out string sorting)
        {
            sorting = "";
            EDC_REPORT EDC_REPORT = new EDC_REPORT();
            try
            {
                info = info.Replace("TestData", "_");
                string[] infos = info.Split('_');
                info = infos[infos.Length - 1];
                info = info.Replace("\r\n", ",");
                info = info.Replace(";", ",");
                string[] bb = info.Split(',');
                int num = bb.Length / 10;
                testData = bb.ToList();

                EDC_REPORT.ProductType = "";
                EDC_REPORT.ProcessMode = "Normal";
                EDC_REPORT.PCBQuantity = num.ToString();
                EDC_REPORT.JobID = PCBID;
                List<string> IDList = GetIDList(PCBID, Convert.ToInt32(EDC_REPORT.PCBQuantity), out sorting );

                int PassNum = 0;
                EDC_REPORT.Pass = 1;
                for (int i = 0; i < num; i++)
                {
                    if (bb[10 + i * 10] == "PASS")
                    {
                        EDC_REPORT.CheckResult += (IDList[i] + "_OK,");
                        PassNum++;
                    }
                    else
                    {
                        EDC_REPORT.Pass = 2;
                        EDC_REPORT.CheckResult += (IDList[i] + "_NG,");
                    }
                }
                EDC_REPORT.CheckResult = EDC_REPORT.CheckResult.Substring(0, EDC_REPORT.CheckResult.Length - 1);
                EDC_REPORT.InitialPassQuantity = PassNum.ToString();
                for (int i = 0; i < IDList.Count; i++)
                {
                    EDC_REPORT.PCBBarcode += IDList[i] + "*";
                }
                EDC_REPORT.PCBBarcode = EDC_REPORT.PCBBarcode.Substring(0, EDC_REPORT.PCBBarcode.Length - 1);

                Random random = new Random();
                double time = Convert.ToDouble(random.Next(300, 500));
                EDC_REPORT.EffectiveTime = FixetureTime;
                EDC_REPORT.AuxiliaryTime = ProcessTime - FixetureTime - WaiteTime;
                EDC_REPORT.WaitingTime = WaiteTime;

                EDC_REPORT.result = true;
            }
            catch
            {
                EDC_REPORT.result = false;
                testData = null;
            }
            return EDC_REPORT;
        }

        public static List<string> GetIDList(string PCBID, int num,out string sorting)
        {
            sorting = "";
            List<string> IDList = new List<string>();
            try
            {
                PCBID = PCBID.Replace("\r", "");
                PCBID = PCBID.Replace("\n", "");
                string initID = PCBID.Substring(0, PCBID.Length - 1);
                string lastID = PCBID.Substring(PCBID.Length - 2, 1);
                int Num = Convert.ToInt16(lastID, 16);
                if (Num <= 16 - num)
                {
                    for (int i = 0; i < num; i++)
                    {
                        string ID = initID + Num.ToString("X");
                        IDList.Add(ID);
                        Num++;
                        sorting = "ASC";
                    }
                }
                else
                {
                    for (int i = 0; i < num; i++)
                    {
                        string ID = initID + Num.ToString("X");
                        IDList.Add(ID);
                        Num--;
                        sorting = "DESC";
                    }
                }
            }
            catch
            {
                for (int i = 0; i < num; i++)
                {
                    IDList.Add("ScanFail");
                }
                sorting = "ERROR";
                return IDList;
            }
            return IDList;
        }
        #endregion

        public static void ReadConfig()
        {
            try
            {
                SBJ_ScanUsing = Convert.ToBoolean(OpearationTxt.ReadIni("上板机", "ScanUsing", "D:\\EQP\\PartList\\Config.ini"));
                SBJ_inputWaiteTime = Convert.ToInt32(OpearationTxt.ReadIni("上板机", "InputWaiteTime", "D:\\EQP\\PartList\\Config.ini"));

                ICT_ScanUsing = Convert.ToBoolean(OpearationTxt.ReadIni("ICT", "ScanUsing", "D:\\EQP\\PartList\\Config.ini"));
                FCT_ScanUsing = Convert.ToBoolean(OpearationTxt.ReadIni("FCT", "ScanUsing", "D:\\EQP\\PartList\\Config.ini"));
            }
            catch
            {
                SBJmode = 2;
                SBJ_ScanUsing = false;
                MessageBox.Show("配方文件读取失败");
            }
        }

        public static void WriteConfig()
        {
            try
            {
                OpearationTxt.WriteIni("上板机", "ScanUsing", SBJ_ScanUsing.ToString(), "D:\\EQP\\PartList\\Config.ini");
                OpearationTxt.WriteIni("上板机", "InputWaiteTime", SBJ_inputWaiteTime.ToString(), "D:\\EQP\\PartList\\Config.ini");
                OpearationTxt.WriteIni("ICT", "ScanUsing", ICT_ScanUsing.ToString(), "D:\\EQP\\PartList\\Config.ini");
                OpearationTxt.WriteIni("FCT", "ScanUsing", FCT_ScanUsing.ToString(), "D:\\EQP\\PartList\\Config.ini");
            }
            catch
            {

            }
        }


    }



    public class OpearationTxt
    {

        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string value, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

        [DllImport("kernel32.dll")]
        static extern uint GetTickCount();


        /// <summary>  
        /// 读ini文件  
        /// </summary>  
        /// <param name="section">节</param>  
        /// <param name="key">键</param>  
        /// <param name="strPath">配置文件路径</param>  
        /// <returns></returns>  
        public static string ReadIni(string section, string key, string strPath)
        {
            try
            {
                StringBuilder temp = new StringBuilder(1024);
                int i = GetPrivateProfileString(section, key, "", temp, 1024, strPath);
                string result = temp.ToString();
                if (result.Contains("\r\n"))
                {
                    result = result.Replace(("\r\n"), ("\r\n"));
                }
                return result;
            }
            catch
            {
                return "";
            }

        }

        /// <summary>  
        /// 写入ini文件  
        /// </summary>  
        /// <param name="section">节</param>  
        /// <param name="key">键</param>  
        /// <param name="value">值</param>  
        /// <param name="strPath">文件路径</param>  
        /// <returns></returns>  
        public static void WriteIni(string section, string key, string value, string strPath)
        {
            if (value.Contains("\r\n"))
            {
                value = value.Replace(("\r\n"), ("\r\n"));
            }
            WritePrivateProfileString(section, key, value, strPath);
        }
        /// <summary>  
        /// 删除节  
        /// </summary>  
        /// <param name="section">节</param>  
        /// <param name="strPath"></param>  
        /// <returns></returns>  
        public static long DeleteSection(string section, string strPath)
        {
            return WritePrivateProfileString(section, null, null, strPath);
        }

        /// <summary>  
        /// 删除键  
        /// </summary>  
        /// <param name="section">节</param>  
        /// <param name="key">键</param>  
        /// <param name="strPath">文件路径</param>  
        /// <returns></returns>  
        public static long DeleteKey(string section, string key, string strPath)
        {
            return WritePrivateProfileString(section, key, null, strPath);
        }

    }
    public class AutoSizeFormClass
    {
        public struct controlRect
        {
            public int Left;
            public int Top;
            public int Width;
            public int Height;
        }

        public List<controlRect> oldCtrl = new List<controlRect>();
        int ctrlNo = 0;

        //重要方法一：记录窗体和其控件的初始位置和大小controllInitializeSize()
        public void controllInitializeSize(Control mForm)
        {
            controlRect cR;
            cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;
            oldCtrl.Add(cR);
            AddControl(mForm);
        }
        private void AddControl(Control ctl)
        {
            foreach (Control c in ctl.Controls)
            {
                controlRect objCtrl;
                objCtrl.Left = c.Left; objCtrl.Top = c.Top; objCtrl.Width = c.Width; objCtrl.Height = c.Height;
                oldCtrl.Add(objCtrl);
                if (c.Controls.Count > 0)
                    AddControl(c);
            }
        }

        //重要方法二：控件自适应大小方法controlAutoSize()
        public void controlAutoSize(Control mForm)
        {
            if (ctrlNo == 0)
            {
                controlRect cR;
                cR.Left = 0; cR.Top = 0; cR.Width = mForm.PreferredSize.Width; cR.Height = mForm.PreferredSize.Height;
                oldCtrl.Add(cR);
                AddControl(mForm);
            }
            float wScale = (float)mForm.Width / (float)oldCtrl[0].Width;
            float hScale = (float)mForm.Height / (float)oldCtrl[0].Height;
            ctrlNo = 1;
            AutoScaleControl(mForm, wScale, hScale);
        }
        private void AutoScaleControl(Control ctl, float wScale, float hScale)
        {
            int ctrLeft0, ctrTop0, ctrWidth0, ctrHeight0;
            foreach (Control c in ctl.Controls)
            {
                ctrLeft0 = oldCtrl[ctrlNo].Left;
                ctrTop0 = oldCtrl[ctrlNo].Top;
                ctrWidth0 = oldCtrl[ctrlNo].Width;
                ctrHeight0 = oldCtrl[ctrlNo].Height;

                c.Left = (int)((ctrLeft0) * wScale);
                c.Top = (int)((ctrTop0) * hScale);//
                c.Width = (int)(ctrWidth0 * wScale);
                c.Height = (int)(ctrHeight0 * hScale);//
                ctrlNo++;
                if (c.Controls.Count > 0)
                    AutoScaleControl(c, wScale, hScale);

                if (ctl is DataGridView)
                {
                    DataGridView dgv = ctl as DataGridView;
                    Cursor.Current = Cursors.WaitCursor;

                    int widths = 0;
                    for (int i = 0; i < dgv.Columns.Count; i++)
                    {
                        dgv.AutoResizeColumn(i, DataGridViewAutoSizeColumnMode.AllCells);  // 自动调整列宽  
                        widths += dgv.Columns[i].Width;   // 计算调整列后单元列的宽度和                       
                    }
                    if (widths >= ctl.Size.Width)  // 如果调整列的宽度大于设定列宽  
                        dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;  // 调整列的模式 自动  
                    else
                        dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;  // 如果小于 则填充  

                    Cursor.Current = Cursors.Default;
                }

            }
        }
    }
    public class RunResult
    {
        /// <summary>
        /// 以数字形式返回操作结果
        /// </summary>
        public int resultID;
        /// <summary>
        /// 以Boolean形式返回操作结果
        /// </summary>
        public bool resultStatic;
        /// <summary>
        /// 以字符串形式返回结果
        /// </summary>
        public string msg;
    }
    public class NetServer
    {
        public Socket ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        /// <summary>
        /// 这是一个处理消息的方法
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="msg"></param>
        private delegate void ProcessMsg(string ip, string msg);
        /// <summary>
        /// 这也是一个处理消息的方法
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="msg"></param>
        public delegate void setProcessMsg(string ip, string msg);
        /// <summary>
        /// 监听服务的IP
        /// </summary>
        private string IpAddress = "0.0.0.0";
        /// <summary>
        /// 监听服务的端口
        /// </summary>
        private int port;
        /// <summary>
        /// 用于存放Socket的列表
        /// </summary>
        private Dictionary<string, Socket> SocketList = new Dictionary<string, Socket>();
        /// <summary>
        /// 用于监听的Socket
        /// </summary>
        private Socket Listener;
        /// <summary>
        /// 消息缓冲区
        /// </summary>
        public byte[] buffer = new byte[1024];
        /// <summary>
        /// 客户端的数量
        /// </summary>
        public int ClientCount { get; set; }
        /// <summary>
        /// 实例一个处理消息的办法
        /// </summary>
        private ProcessMsg MsgProcess;
        /// <summary>
        /// 存放当前运行状态的相关信息
        /// </summary>
        public List<string> RunMsg = new List<string>();


        /// <summary>
        /// 开启一个监听服务
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public RunResult Start(int port)
        {
            this.port = port;
            RunResult runresult = new RunResult();
            try
            {
                Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint IPEndPoint = new IPEndPoint(IPAddress.Parse(IpAddress), port);
                Listener.Bind(IPEndPoint);
                Listener.Listen(ClientCount);
                Listener.BeginAccept(Accept, null);

                runresult.resultID = 0;
                runresult.msg = "创建服务成功";
            }
            catch (Exception error)
            {
                runresult.resultID = -1;
                runresult.msg = "创建服务失败 /r/n" + error.Message;
            }
            return runresult;
        }
        /// <summary>
        /// 当有客户端连接时的回调函数
        /// </summary>
        /// <param name="ar"></param>
        private void Accept(IAsyncResult ar)
        {
            Socket socket = Listener.EndAccept(ar);
            string adr = socket.RemoteEndPoint.ToString();
            string[] name = adr.Split(':');
            Console.WriteLine(name[0] + "已连接");
            bool checkResult = false;
            foreach (KeyValuePair<string, Socket> i in SocketList)
            {
                if (i.Key == name[0])
                {
                    checkResult = true;
                }
            }
            if (checkResult == true)
            {
                SocketList.Remove(name[0]);
            }
            SocketList.Add(name[0], socket);
            socket.BeginReceive(buffer, 0, 1024, SocketFlags.None, ReceiveCb, socket);
            Listener.BeginAccept(Accept, null);
        }
        /// <summary>
        /// 当有消息接收到的回调函数
        /// </summary>
        /// <param name="ar"></param>
        private void ReceiveCb(IAsyncResult ar)
        {
            Socket read = (Socket)ar.AsyncState;
            string ClientName = "";
            try
            {
                int count = read.EndReceive(ar);
                string[] name = read.RemoteEndPoint.ToString().Split(':');
                if (count <= 0)
                {
                    Addinfo(name[0] + ": 客户端已经主动断开");
                    read.Close();
                    SocketList.Remove(name[0]);
                }
                string info = Encoding.Default.GetString(buffer, 0, count);
                ClientName = name[0];
                MsgProcess(name[0], info);
                // read.BeginReceive(buffer, 0, 1024, SocketFlags.None, ReceiveCb, read);
            }

            catch (Exception error)
            {

                Console.WriteLine(error.Message);
                return;
            }
        }
        private void ClientReceiveCb(IAsyncResult ar)
        {
            Socket read = (Socket)ar.AsyncState;
            try
            {
                int count = read.EndReceive(ar);
                string info = Encoding.UTF8.GetString(buffer, 0, count);

                MsgProcess("0.0.0.0", info);
                ClientSocket.BeginReceive(buffer, 0, 1024, SocketFlags.None, ClientReceiveCb, ClientSocket);
            }

            catch (Exception error)
            {

                Console.WriteLine(error.Message);
                return;
            }
        }
        /// <summary>
        /// 这是处理消息的回调实现
        /// </summary>
        /// <param name="msgHandle"></param>
        public void SetMsgHandle(setProcessMsg msgHandle)
        {
            MsgProcess = new ProcessMsg(msgHandle);
        }

        private void Addinfo(string info)
        {

            if (RunMsg.Count > 20)
            {
                RunMsg.RemoveAt(0);
            }
            RunMsg.Add(info);
        }


        /// <summary>
        /// 这是主动连接一个服务端的方法
        /// </summary>
        /// <param name="ip">服务端的地址</param>
        /// <param name="port">服务端口</param>
        public int Connect(string ip, int port)
        {
            try
            {
                ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ipaddr = IPAddress.Parse(ip);
                IPEndPoint ipendpoint = new IPEndPoint(ipaddr, port);
                ClientSocket.Connect(ipendpoint);
                SocketList.Clear();
                SocketList.Add(ip, ClientSocket);
                ClientSocket.BeginReceive(buffer, 0, 1024, SocketFlags.None, ClientReceiveCb, ClientSocket);
                return 0;
            }
            catch (Exception error)
            {
                Console.WriteLine(error.Message);
                return -1;
            }

        }
        /// <summary>
        /// 这是主动向客户端发送消息的办法
        /// </summary>
        /// <param name="ClientIP">客户端地址</param>
        /// <param name="info">客户端口</param>
        public void SendMsg(string ClientIP, string info)
        {
            byte[] msg = new byte[1024 * 1024];
            msg = Encoding.Default.GetBytes(info);
            SocketList[ClientIP].Send(msg);
        }
        public void ClientSendMSG(string info)
        {
            try
            {
                byte[] msg = Encoding.Default.GetBytes(info);
                ClientSocket.Send(msg);
            }
            catch
            {

            }

        }
        public void ClientSendMSG(byte[] msg)
        {

            ClientSocket.Send(msg);


        }
        /// <summary>
        /// 获取当前客户端的连接数量
        /// </summary>
        /// <returns></returns>
        public int GetConnectCount()
        {
            return SocketList.Count;
        }

        public int DisConnect()
        {
            try
            {
                ClientSocket.Disconnect(true);
                return 0;
            }
            catch
            {
                return -1;
            }
        }



        public void KeepConnect(string ip, int port)
        {
            Task ConnectEndPoint = new Task(() => { ConnectPoint(ip, port); });
        }

        private void ConnectPoint(string IP, int port)
        {
            while (true)
            {
                bool MySocketFlag = true;
                if (SocketList.Count != 0)
                {
                    foreach (KeyValuePair<string, Socket> i in SocketList)
                    {
                        if (i.Key == IP)
                        {
                            MySocketFlag = true;
                        }
                    }
                }

                if (MySocketFlag == false)
                {
                    Connect(IP, port);
                }
            }
        }






    }
    public class DateTimeSynchronization
    {
        [StructLayout(LayoutKind.Sequential)]
        private struct Systemtime
        {
            public short year;
            public short month;
            public short dayOfWeek;
            public short day;
            public short hour;
            public short minute;
            public short second;
            public short milliseconds;
        }

        [DllImport("kernel32.dll")]
        private static extern bool SetLocalTime(ref Systemtime time);

        private static uint swapEndian(ulong x)
        {
            return (uint)(((x & 0x000000ff) << 24) +
            ((x & 0x0000ff00) << 8) +
            ((x & 0x00ff0000) >> 8) +
            ((x & 0xff000000) >> 24));
        }

        /// <summary>
        /// 设置系统时间
        /// </summary>
        /// <param name="dt">需要设置的时间</param>
        /// <returns>返回系统时间设置状态，true为成功，false为失败</returns>
        public static bool SetLocalDateTime(DateTime dt)
        {
            Systemtime st;
            st.year = (short)dt.Year;
            st.month = (short)dt.Month;
            st.dayOfWeek = (short)dt.DayOfWeek;
            st.day = (short)dt.Day;
            st.hour = (short)dt.Hour;
            st.minute = (short)dt.Minute;
            st.second = (short)dt.Second;
            st.milliseconds = (short)dt.Millisecond;
            bool rt = SetLocalTime(ref st);
            return rt;
        }

    }
    public class Product
    {
        public static string LastPart = "";

        public static List<string> productList = new List<string>();

        public static string RecipeID { get; set; }
        public static string RecipeVersion { get; set; }



        public static Dictionary<string, string> RecipeParameterList = new Dictionary<string, string>();
        public static void ReadPartList()
        {
            try
            {
                string[] parts = Directory.GetFiles("D:\\EQP\\PartList");
                productList = parts.ToList();
            }
            catch
            {
                MessageBox.Show("配方文件读取失败");
            }
        }

        public static void LoadLastPart()
        {
            try
            {
                LastPart = OpearationTxt.ReadIni("LastPart", "LastPart", "D:\\EQP\\Config.ini");
                ReadPart(LastPart);
            }
            catch
            {

            }
        }

        public static void ReadPart(string recipeID)
        {
            try
            {
                double bankuan = Convert.ToDouble(OpearationTxt.ReadIni("Product", "bankuan", "D:\\EQP\\PartList\\" + recipeID + ".ini"));
                RecipeParameterList.Clear();
                RecipeParameterList.Add("板宽", bankuan.ToString());
                RecipeVersion = OpearationTxt.ReadIni("Product", "RecipeVersion", "D:\\EQP\\PartList\\" + recipeID + ".ini");
                RecipeID = recipeID;
            }
            catch
            {
                MessageBox.Show("配方文件读取失败");
            }
        }
        public static void WritePart(string partName, double bankuan)
        {
            if (!File.Exists("D:\\EQP\\PartList\\" + partName + ".ini"))
            {
                File.Create("D:\\EQP\\PartList\\" + partName + ".ini");
            }
            OpearationTxt.WriteIni("Product", "bankuan", bankuan.ToString(), "D:\\EQP\\PartList\\" + RecipeID + ".ini");
            OpearationTxt.WriteIni("Product", "RecipeVersion", RecipeVersion.ToString(), "D:\\EQP\\PartList\\" + RecipeID + ".ini");

        }
    }

    public class EDC_REPORT
    {
        public bool result = false;
        public int Pass = 1;

        public string JobID = "";
        public string ProductType = "";
        public string ProcessMode = "";
        public string PCBQuantity = "";
        public string PCBBarcode = "";
        public string InitialPassQuantity = "";
        public string CheckResult = "";

        public int ProcessTime = 0;
        public int EffectiveTime = 0;
        public int AuxiliaryTime = 0;
        public int WaitingTime = 0;
    }
}

